package controller

import (
	"github.com/gin-gonic/gin"
	"golang.org/x/crypto/bcrypt"
	"gorm.io/gorm"
	"log"
	"net/http"
	"uniquen.top/golang-demo/common"
	"uniquen.top/golang-demo/dto"
	"uniquen.top/golang-demo/model"
	"uniquen.top/golang-demo/response"
	"uniquen.top/golang-demo/utils"
)

func Register(ctx *gin.Context) {

	DB := common.DB

	// 获取参数
	name := ctx.PostForm("name")
	tel := ctx.PostForm("tel")
	password := ctx.PostForm("password")

	// 数据校验
	if len(tel) != 11 {
		ctx.JSON(http.StatusUnprocessableEntity, gin.H{"code": 422, "msg": "手机号必须为11位"})
		return
	}

	if len(password) < 6 {
		response.Fail(ctx, http.StatusUnprocessableEntity, 422, nil, "密码不能少于6位")
		return
	}

	// 判断手机号是否存在
	if isTelExist(DB, tel) {
		response.Fail(ctx, http.StatusUnprocessableEntity, 422, nil, "用户已存在")
		return
	}

	if len(name) == 0 {
		// 生成随机name
		name = utils.RandomString(10)
	}

	// 密码加密
	hashPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
	if err != nil {
		response.Fail(ctx, http.StatusInternalServerError, 500, nil, "密码加密错误")
		return
	}

	newUser := model.User{
		Name:     name,
		Password: string(hashPassword),
		Tel:      tel,
	}

	DB.Create(&newUser)

	log.Printf("name: %s, password: %s, tel: %s\n", name, password, tel)

	response.Success(ctx, nil, "注册成功")

}

func Login(ctx *gin.Context) {
	DB := common.GetDB()

	// 获取参数
	tel := ctx.PostForm("tel")
	password := ctx.PostForm("password")

	// 数据校验
	if len(tel) != 11 {
		response.Fail(ctx, http.StatusUnprocessableEntity, 422, nil, "手机号必须为11位")
		return
	}

	if len(password) < 6 {
		response.Fail(ctx, http.StatusUnprocessableEntity, 422, nil, "密码不能少于6位")
		return
	}

	var user model.User
	DB.Where("tel = ?", tel).First(&user)
	if user.ID == 0 {
		response.Fail(ctx, http.StatusUnprocessableEntity, 422, nil, "用户不存在")
		return
	}

	// 密码验证
	if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password)); err != nil {
		response.Fail(ctx, http.StatusBadRequest, 400, nil, "密码错误")
		return
	}

	// 生成token
	token, err := utils.ReleaseToken(user)
	if err != nil {
		log.Printf("token generate error : %v", err)
		response.Fail(ctx, http.StatusInternalServerError, 500, nil, "系统错误")
		return
	}

	response.Success(ctx, gin.H{"token": token}, "登录成功")

}

func Info(ctx *gin.Context) {

	user, _ := ctx.Get("user")

	response.Success(ctx, gin.H{"user": dto.ToUserInfoDTO(user.(model.User))}, "获取成功")
}

func isTelExist(db *gorm.DB, tel string) bool {
	var user model.User
	db.Where("tel = ?", tel).First(&user)

	return user.ID != 0
}
